#pragma once
#include "elisa/elisa.h"
#include <iostream>
#include <sstream>
#include <algorithm>
#include <string>
#include <vector>
#include <gaol/gaol>

#include "Modeler.h"

#ifdef ELISA_PERFORMER
#include "elisa_chrono.h"
#endif

using namespace std;
using namespace elisa;

class Floudas2 : public Modeler
{
private:
	Model _model;

	RealVar x1;
	RealVar x2;
	RealVar p;
	RealConstraint c1;
	RealConstraint c2;

public:
	Floudas2()
		: x1(Interval(0.25,1), "x1"),
		  x2(Interval(1.5,2*Interval::Pi.sup()), "x2"),
		  p(Interval::Pi, "p"),
		  c1(0.5*sin(x1*x2) - 0.25*x2/p -0.5*x1 == 0),
		  c2((1-0.25/p)*(exp(2*x1)-2.71828183) + 2.71828183*x2/p - 2*2.71828183*x1 == 0), // e = exp(1) = 2.71828183
		  _model()
	{
	}

	elisa::Model & model()
	{
		_model = c1 && c2;
		return _model;
	}

	void print()
	{
		cout << '\t' << x1.getName() << " = " << x1.domain() << endl;
		cout << '\t' << x2.getName() << " = " << x2.domain() << endl;
	}

	RealVar & varX()
	{
		return x1;
	}
	RealVar & varY()
	{
		return x2;
	}
};
